package ldk.util.scrollviews

import android.content.Context
import android.support.v4.view.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.webkit.WebView

/**
 *
 * Created by ldkxingzhe@163.com on 2017/9/10.
 */
class NestedWebView : WebView, NestedScrollingChild{
    companion object {
        private val TAG = "NestedWebView"
        var DEBUG = true
    }

    private var mLastY: Int = 0
    private val mScrollOffset = IntArray(2)
    private val mScrollConsumed = IntArray(2)
    private var mNestedYOffset = 0
    private var mChildHelper = NestedScrollingChildHelper(this)

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, privateBrowsing: Boolean) : super(context, attrs, defStyleAttr, privateBrowsing)


    override fun onTouchEvent(event: MotionEvent?): Boolean {
        var returnValue = false

        val fakeEvent = MotionEvent.obtain(event)
        val action = MotionEventCompat.getActionMasked(fakeEvent)
        if (action == MotionEvent.ACTION_DOWN){
            mNestedYOffset = 0
        }
        val eventY = fakeEvent.y
        fakeEvent.offsetLocation(0f, mNestedYOffset.toFloat())
        when(action){
            MotionEvent.ACTION_MOVE->{
                var deltaY:Int = (mLastY - eventY).toInt()
                // NestedScroll
                if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)){
                    deltaY -= mScrollConsumed[1]
                    mLastY = (eventY - mScrollOffset[1]).toInt()
                    fakeEvent.offsetLocation(0f, (-mScrollOffset[1]).toFloat())
                    mNestedYOffset += mScrollOffset[1]
                }

                returnValue = super.onTouchEvent(fakeEvent)
                // NestedScroll
                if (dispatchNestedScroll(0, mScrollOffset[1], 0, deltaY, mScrollOffset)){
                    fakeEvent.offsetLocation(0f, mScrollOffset[1].toFloat())
                    mNestedYOffset += mScrollOffset[1]
                    mLastY -= mScrollOffset[1]
                }
            }
            MotionEvent.ACTION_DOWN->{
                returnValue = super.onTouchEvent(fakeEvent)
                mLastY = eventY.toInt()
                // startNestedScroll
                startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL)
            }

            MotionEvent.ACTION_UP,
            MotionEvent.ACTION_CANCEL->{
                returnValue = super.onTouchEvent(fakeEvent)
                stopNestedScroll()
            }
        }
        return returnValue
    }

    override fun setNestedScrollingEnabled(enabled: Boolean) {
        mChildHelper.isNestedScrollingEnabled = enabled
    }

    override fun isNestedScrollingEnabled(): Boolean {
        return mChildHelper.isNestedScrollingEnabled
    }

    override fun startNestedScroll(axes: Int): Boolean {
        return mChildHelper.startNestedScroll(axes)
    }

    override fun stopNestedScroll() {
        mChildHelper.stopNestedScroll()
    }

    override fun hasNestedScrollingParent(): Boolean {
        return mChildHelper.hasNestedScrollingParent()
    }

    override fun dispatchNestedScroll(dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?): Boolean {
        return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow)
    }

    override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?): Boolean {
        return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow)
    }

    override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean): Boolean {
        return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed)
    }

    override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float): Boolean {
        return mChildHelper.dispatchNestedPreFling(velocityX, velocityY)
    }

    fun scrollBy(deltaY: Int){
        val oldScrollY = scrollY
        scrollBy(0, deltaY)
        val consumedScrollY = scrollY - oldScrollY
        val unConsumedScrollY = deltaY - consumedScrollY
        dispatchNestedScroll(0, consumedScrollY, 0, unConsumedScrollY, null)
    }
}